﻿using System;
using System.Data;
using System.Data.Common;
using System.Collections;
using System.Data.SqlClient;
using System.Xml;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.Configuration;
using System.Text;
using System.Collections.Specialized;
using System.Globalization;


namespace MySQLStudio.Common
{    
    public class SecUtility
    {
        internal static Regex IsGuid = new Regex(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", RegexOptions.Compiled);                       
      
        public static bool GetBooleanValue(NameValueCollection config, string valueName, bool defaultValue)
        {
            string sValue = config[valueName];
            if (sValue == null)
            {
                return defaultValue;
            }

            bool result;
            if (bool.TryParse(sValue, out result))
            {
                return result;
            }
            else
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_boolean, valueName));
            }
        }

        public static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, int maxValueAllowed)
        {
            string sValue = config[valueName];

            if (sValue == null)
            {
                return defaultValue;
            }

            int iValue;
            if (!Int32.TryParse(sValue, out iValue))
            {
                if (zeroAllowed)
                {
                    throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_non_negative_integer, valueName));
                }

                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_positive_integer, valueName));
            }

            if (zeroAllowed && iValue < 0)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_non_negative_integer, valueName));
            }

            if (!zeroAllowed && iValue <= 0)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_positive_integer, valueName));
            }

            if (maxValueAllowed > 0 && iValue > maxValueAllowed)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_too_big, valueName, maxValueAllowed.ToString(CultureInfo.InvariantCulture)));
            }

            return iValue;
        }

        public static int GetIntValue(NameValueCollection config, string valueName, int defaultValue, bool zeroAllowed, bool negativeAllowed, int maxValueAllowed)
        {
            int iValue;
            string sValue = config[valueName];

            if (string.IsNullOrEmpty(config[valueName]))
                return defaultValue;

            if (!int.TryParse(sValue, out iValue))
                throw new ArgumentException(string.Format("Invalid integer value - {0}", sValue));

            if (!zeroAllowed && iValue == 0)
                throw new ArgumentException("Invalid value : zero not allowed");

            if (!negativeAllowed && iValue < 0)
                throw new ArgumentException("Invalid value : negative not allowed");

            if (iValue > maxValueAllowed)
                throw new ArgumentException(string.Format("Invalid value : greater then  - {0}", maxValueAllowed));


            return iValue;
        }

        public static int GetIntValue(string value, int defaultValue, bool zeroAllowed, bool negativeAllowed, int maxValueAllowed)
        {
            int iValue;
            if (string.IsNullOrEmpty(value))
                return iValue = defaultValue;

            if (!int.TryParse(value, out iValue))
                throw new ArgumentException(string.Format("Invalid integer value - {0}", value));

            if (!zeroAllowed && iValue == 0)
                throw new ArgumentException("Invalid value : zero not allowed");

            if (!negativeAllowed && iValue < 0)
                throw new ArgumentException("Invalid value : negative not allowed");

            if (iValue > maxValueAllowed)
                throw new ArgumentException(string.Format("Invalid value : greater then  - {0}", maxValueAllowed));


            return iValue;
        }

        public static int? GetIntValue(string value, int minValueAllowed, int maxValueAllowed)
        {
            int iValue;

            if (string.IsNullOrEmpty(value))
                return null;

            if (!int.TryParse(value, out iValue))
                return null;

            if ((iValue > maxValueAllowed) || (iValue < minValueAllowed))
                return null;

            return iValue;
        }

        public static int? GetIntValue(NameValueCollection collection, string valueName, int minValueAllowed, int maxValueAllowed)
        {
            string sValue;
            int iValue;

            sValue = collection[valueName];
            if (string.IsNullOrEmpty(sValue))
                return null;

            if (!int.TryParse(sValue, out iValue))
                return null;

            if ((iValue > maxValueAllowed) || (iValue < minValueAllowed))
                return null;

            return iValue;
        }

        public static int GetIntValue(string value, int defaultValue)
        {
            int iValue = defaultValue;
            if (!string.IsNullOrEmpty(value))
            {
                if (!int.TryParse(value, out iValue))
                    iValue = defaultValue;
            }
            else
                iValue = defaultValue;

            return iValue;
        }
        

        public static bool ValidateParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize)
        {
            if (param == null)
            {
                return !checkForNull;
            }

            param = param.Trim();
            if ((checkIfEmpty && param.Length < 1) ||
                 (maxSize > 0 && param.Length > maxSize) ||
                 (checkForCommas && param.Contains(",")))
            {
                return false;
            }

            return true;
        }

        public static void CheckParameter(ref string param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName)
        {
            if (param == null)
            {
                if (checkForNull)
                {
                    throw new ArgumentNullException(paramName);
                }

                return;
            }

            param = param.Trim();
            if (checkIfEmpty && param.Length < 1)
            {
                throw new ArgumentException(ErrorMessages.GetString(ErrorMessages.Parameter_can_not_be_empty, paramName), paramName);
            }

            if (maxSize > 0 && param.Length > maxSize)
            {
                throw new ArgumentException(ErrorMessages.GetString(ErrorMessages.Parameter_too_long, paramName, maxSize.ToString(CultureInfo.InvariantCulture)), paramName);
            }

            if (checkForCommas && param.Contains(","))
            {
                throw new ArgumentException(ErrorMessages.GetString(ErrorMessages.Parameter_can_not_contain_comma, paramName), paramName);
            }
        }

        public static int GetIntValue(string value, int defaultValue, int minValue, int maxValue)
        {
            int iValue = defaultValue;
            if (!string.IsNullOrEmpty(value))
            {
                bool isValid = int.TryParse(value, out iValue);
                if (!isValid)
                    return defaultValue;
                else
                {
                    if (iValue >= minValue && iValue <= maxValue)
                        return iValue;
                    else
                        return defaultValue;
                }
            }
            else
                iValue = defaultValue;

            return iValue;
        }

        public static long GetLongValue(NameValueCollection config, string valueName, long defaultValue, bool zeroAllowed, long maxValueAllowed)
        {
            string sValue = config[valueName];

            if (sValue == null)
            {
                return defaultValue;
            }

            long lValue;
            if (!Int64.TryParse(sValue, out lValue))
            {
                if (zeroAllowed)
                {
                    throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_non_negative_integer, valueName));
                }

                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_positive_integer, valueName));
            }

            if (zeroAllowed && lValue < 0)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_non_negative_integer, valueName));
            }

            if (!zeroAllowed && lValue <= 0)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_must_be_positive_integer, valueName));
            }

            if (maxValueAllowed > 0 && lValue > maxValueAllowed)
            {
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_too_big, valueName, maxValueAllowed.ToString(CultureInfo.InvariantCulture)));
            }

            return lValue;
        }


        public static DateTime GetDateTimeValue(NameValueCollection config, string valueName, DateTime defaultValue)
        {
            string sValue = config[valueName];

            if (sValue == null)
                return defaultValue;

            CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;

            DateTime dValue;

            if (!DateTime.TryParse(sValue, ci, DateTimeStyles.None, out dValue))
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_is_not_valid_datetime, valueName));

            return dValue;
        }

        /// <summary>
        /// Get date from string representation
        /// </summary>
        /// <param name="dateValue"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static DateTime GetDateTimeValue(string dateValue, DateTime defaultValue)
        {
            if (dateValue == null)
                return defaultValue;

            CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;

            DateTime dValue;

            if (!DateTime.TryParse(dateValue, ci, DateTimeStyles.None, out dValue))
                throw new ApplicationException(ErrorMessages.GetString(ErrorMessages.Value_is_not_valid_datetime, dateValue));

            return dValue;
        }

        public static string GetStringValue(NameValueCollection config, string valueName, string defaultValue)
        {
            string sValue = config[valueName];

            if (sValue == null)
            {
                return defaultValue;
            }

            return sValue;
        }

        public static string GetStringValue(string value, string defaultValue)
        {
            return value != null ? value : defaultValue;
        }

        public static bool GetBoolValue(string value, bool defaultValue)
        {
            bool bValue = defaultValue;
            if (!string.IsNullOrEmpty(value))
            {
                if (!bool.TryParse(value, out bValue))
                    bValue = defaultValue;
            }
            else
                bValue = defaultValue;

            return bValue;
        }

        public static bool GetBoolValue(NameValueCollection config, string valueName, bool defaultValue)
        {
            bool bValue = defaultValue;

            string sValue = config[valueName];
            if (sValue == null)
                bValue = defaultValue;
            else
            {
                if (!bool.TryParse(sValue, out bValue))
                    bValue = defaultValue;
            }

            return bValue;
        }

        public static Guid GetGuidValue(string value)
        {
            Guid outputGuid = Guid.Empty;
            if (!string.IsNullOrEmpty(value))
            {
                if (IsGuid.IsMatch(value))
                    outputGuid = new Guid(value);
            }
            return outputGuid;
        }

        public static void CheckArrayParameter(ref string[] param, bool checkForNull, bool checkIfEmpty, bool checkForCommas, int maxSize, string paramName)
        {
            if (param == null)
            {
                throw new ArgumentNullException(paramName);
            }

            if (param.Length < 1)
            {
                throw new ArgumentException(ErrorMessages.GetString(ErrorMessages.Parameter_array_empty, paramName), paramName);
            }

            Hashtable values = new Hashtable(param.Length);
            for (int i = param.Length - 1; i >= 0; i--)
            {
                SecUtility.CheckParameter(ref param[i], checkForNull, checkIfEmpty, checkForCommas, maxSize,
                    paramName + "[ " + i.ToString(CultureInfo.InvariantCulture) + " ]");
                if (values.Contains(param[i]))
                {
                    throw new ArgumentException(ErrorMessages.GetString(ErrorMessages.Parameter_duplicate_array_element, paramName), paramName);
                }
                else
                {
                    values.Add(param[i], param[i]);
                }
            }
        }
    }
}
